package com.lwj.mallchat.common.user.service.impl;

import com.lwj.mallchat.common.common.annotation.RedissonLock;
import com.lwj.mallchat.common.common.domain.enums.YesOrNoEnum;
import com.lwj.mallchat.common.common.service.LockService;
import com.lwj.mallchat.common.common.utils.AssertUtil;
import com.lwj.mallchat.common.user.dao.UserBackpackDao;
import com.lwj.mallchat.common.user.domain.entity.UserBackpack;
import com.lwj.mallchat.common.user.domain.enums.IdempotentEnum;
import com.lwj.mallchat.common.user.service.UserBackpackService;
import lombok.extern.slf4j.Slf4j;
import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import java.util.Objects;

/**
 * @author lwj
 * @ClassName UserBackpackServiceImpl
 * @date 2024/10/21 15:23
 */
@Service
@Slf4j
public class UserBackpackServiceImpl implements UserBackpackService {
    @Autowired
    private RedissonClient redissonClient;

    @Autowired
    private LockService lockService;

    @Autowired
    private UserBackpackDao userBackpackDao;

    @Autowired
    @Lazy
    private UserBackpackServiceImpl userBackpackService;


    @Override
    public void acquireItem(Long uid, Long itemId, IdempotentEnum idempotentEnum, String businessId) {
//                                初始版本
//        String idempotent = getIdempotent(itemId, idempotentEnum, businessId);
//        RLock lock = redissonClient.getLock("acquireItem" + idempotent);
//        boolean b = lock.tryLock();
//        AssertUtil.isTrue(b, "请求太频繁了");
//        try {
//            UserBackpack userBackpack = userBackpackDao.getByIdempotent(idempotent);
//            if (Objects.nonNull(userBackpack)) {
//                return;
//            }
//            //发放物品
//            UserBackpack backpack = UserBackpack.builder()
//                    .idempotent(idempotent)
//                    .itemId(itemId)
//                    .status(YesOrNoEnum.NO.getStatus())
//                    .uid(uid)
//                    .build();
//            userBackpackDao.save(backpack);
//        } finally {
//            lock.unlock();
//        }
        String idempotent = getIdempotent(itemId, idempotentEnum, businessId);
        userBackpackService.doAcquireItem(uid, itemId, idempotent, businessId);
    }

    @RedissonLock(key = "#idempotent", waitTime = 5000)
    public void doAcquireItem(Long uid, Long itemId, String idempotent, String businessId) {
        lockService.executeWithLock("acquireItem" + idempotent, () -> {
                    UserBackpack userBackpack = userBackpackDao.getByIdempotent(idempotent);
                    if (Objects.nonNull(userBackpack)) {
                        return;
                    }
                    //发放物品
                    UserBackpack backpack = UserBackpack.builder()
                            .idempotent(idempotent)
                            .itemId(itemId)
                            .status(YesOrNoEnum.NO.getStatus())
                            .uid(uid)
                            .build();
                    userBackpackDao.save(backpack);
                }
        );
    }


    private String getIdempotent(Long itemId, IdempotentEnum idempotentEnum, String businessId) {
        return String.format("%d_%d_%s", itemId, idempotentEnum.getType(), businessId);
    }
}
